﻿
namespace MockingBird.Studio.UI.UserControls.ModelBuilders
{
    using System.Collections.Generic;
    using System.ServiceModel.Description;
    using MockingBird.Studio.UI.UserControls.Model;
    using Thinktecture.Tools.Wscf.Services.ServiceDescription.Contract;

    /// <summary>
    /// Builds a WsdlDocument from the service definition
    /// </summary>
    public class WsdlDocumentBuilder
    {
        private WsdlDocument wsdlDoc;
        private ServiceDefinition serviceDefinition;

        public WsdlDocumentBuilder()
        {
            this.wsdlDoc = new WsdlDocument();
            this.wsdlDoc.Operations = new List<WsdlOperation>();
            this.serviceDefinition = new ServiceDefinition();
        }

        public WsdlDocument BuildWsdlFromServiceDefinition(ServiceDefinition targetServiceDefinition)
        {
            this.serviceDefinition = targetServiceDefinition;

            this.BuildServiceElement();

            foreach (OperationDescription od in this.serviceDefinition.Operations)
            {
                this.BuildOperationElement(od);
            }

            // add the schemas
            this.wsdlDoc.WsdlSchemaSet = this.serviceDefinition.SchemaSet;

            return this.wsdlDoc;

        }

        private void BuildServiceElement()
        {
            this.wsdlDoc.Service = new WsdlService();
            this.wsdlDoc.Service.Load(this.serviceDefinition);
        }

        private void BuildOperationElement(OperationDescription sourceOp)
        {
            WsdlOperation wsdlOp = new WsdlOperation();
            wsdlOp.Load(sourceOp);

            MessageDescription sourceInputMsg = ServiceDefinition.FindOperationMessage(sourceOp, MessageDirection.Input);
            wsdlOp.InputMessage = new WsdlMessage();
            wsdlOp.InputMessage.Load(sourceInputMsg);

            MessageDescription sourceOutputMsg = null;

            if (!wsdlOp.IsOneWay)
            {
                sourceOutputMsg = ServiceDefinition.FindOperationMessage(sourceOp, MessageDirection.Output);
                wsdlOp.OutputMessage = new WsdlMessage();
                wsdlOp.OutputMessage.Load(sourceOutputMsg);
            }

            // Add this operation element to the wsdl document
            this.wsdlDoc.Operations.Add(wsdlOp);
        }
    }
}
